package com.wanrue.tcc.common;

import com.wanrue.tcc.context.Context;
import com.wanrue.tcc.enums.Propagation;
import com.wanrue.tcc.enums.Role;
import lombok.Data;

import java.io.Serializable;
import java.lang.reflect.Method;

/**
 * tcc 方法的注解信息
 * Created by wenjie on 10/15/18.
 */
@Data
public class TccMethod implements Serializable {

    private Object target;

    private Class targetClass;

    private Method method;

    private String methodName;

    private Object[] args;

    private Class<?>[] parameterTypes;

    private String confirm;

    private String cancel;

    private Context context;

    private boolean asyncCancel;

    private boolean asyncConfirm;

    private Propagation propagation;

    public Object proceed() throws Throwable {
        return method.invoke(target, args);
    }

    public Object getValue() {
        Class type = method.getReturnType();
        if (boolean.class.equals(type)) {
            return false;
        } else if (byte.class.equals(type)) {
            return 0;
        } else if (short.class.equals(type)) {
            return 0;
        } else if (int.class.equals(type)) {
            return 0;
        } else if (long.class.equals(type)) {
            return 0;
        } else if (float.class.equals(type)) {
            return 0;
        } else if (double.class.equals(type)) {
            return 0;
        } else {
            return null;
        }
    }

    public Role role(boolean isTransactionActive) {
        if ((propagation.equals(Propagation.REQUIRED) && !isTransactionActive && context == null) || propagation.equals(Propagation.REQUIRES_NEW)) {
            return Role.INITIATOR;
        } else if ((propagation.equals(Propagation.REQUIRED) || propagation.equals(Propagation.MANDATORY)) && !isTransactionActive && context != null) {
            return Role.PARTICIPANT;
        } else {
            return Role.NORMAL;
        }
    }

    public boolean isLegalContext(boolean isTransactionActive) {
        if (propagation.equals(Propagation.MANDATORY) && !isTransactionActive && context == null) return false;
        return true;
    }

}
